﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using housingsafety.server.Attributes;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace housingsafety.server.Filters
{
    public class AddFileParamTypesOperationFilter : IOperationFilter
    {
        private readonly string[] _fileParameters = new[] { "ContentType", "ContentDisposition", "Headers", "Length", "Name", "FileName" };

        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var operationHasFileUploadButtons = context.MethodInfo.GetCustomAttributes(true)
                .OfType<AddSwaggerFileUploadButtonAttribute>().ToArray();
            var operationHasFileUploadButton = operationHasFileUploadButtons.Any();

            if (!operationHasFileUploadButton)
            {
                return;
            }

            RemoveExistingFileParameters(operation.Parameters);
            if (operation.RequestBody != null && operation.RequestBody.Content.ContainsKey("multipart/form-data"))
            {
                for (int i = 0; i < operationHasFileUploadButtons[0].Count; i++)
                {
                    operation.RequestBody.Content["multipart/form-data"]
                        .Schema.Properties.Add($"formFile{i}", new OpenApiSchema()
                        {
                            Description = "Select file",
                            Type = "string",
                            Format = "binary"
                        });
                }
            }
            else
            {
                IDictionary<string, OpenApiSchema> properties = new Dictionary<string, OpenApiSchema>();
                for (int i = 0; i < operationHasFileUploadButtons[0].Count; i++)
                {
                    properties.Add($"formFile{i}", new OpenApiSchema()
                    {
                        Description = "Select file",
                        Type = "string",
                        Format = "binary"
                    });
                }

                operation.RequestBody = new OpenApiRequestBody()
                {
                    Content =
                    {
                        ["multipart/form-data"] = new OpenApiMediaType()
                        {
                            Schema = new OpenApiSchema()
                            {
                                Type = "object",
                                Properties =properties
                            }
                        }
                    }
                };
            }

        }

        private void RemoveExistingFileParameters(IList<OpenApiParameter> operationParameters)
        {
            foreach (var parameter in operationParameters.Where(p => p.In == ParameterLocation.Query
                                                                     && _fileParameters.Contains(p.Name)).ToList())
            {
                operationParameters.Remove(parameter);
            }
        }
    }
}
